/***********************************************************************************
 * 文件名： knob.c
 * 版本： 1
 * 说明：
 * 		knob(旋钮电位器)，设定一个范围，电位器输出这个范围的值。
 * 修改记录：
 * 	2021/07/07: 初版。
***********************************************************************************/
#include "knob.h"
#include "polsys.h"

volatile u16 _Knob_Value;
static Knob_ev_t Knob_mEvent = KNOB_EV_NULL;
static bit Knob_mRun = false;
static u16 _Knob_RangeDValue;
static u16 _Knob_RangeLowValue;
// 声明引用事件通知函数（避免使用函数指针的妥协）
// 在你的应用代码中定义这个函数用于接收事件
void Knob_Event(Knob_ev_t e);

//初始化
void Knob_Init(void)
{
    _KNOB_InitADC();
}

//开启自动刷新
void Knob_StartAutoRefresh(void)
{
    Knob_mRun = true;
}

//停止自动刷新
void Knob_StopAutoRefresh(void)
{
    Knob_mRun = false;
}

//获取一次旋钮值
u16 Knob_GetValue(void)
{
    u8 adv;

    _KNOB_SetADCH_ANALOG();
    adv = _KNOB_GetADValue();
    _KNOB_SetADCH_DIGIT();
    
#ifdef _KNOB_USE_SET_RANGE
    _Knob_Value = (u16)((u32)((u32)adv * (u16)((u32)(_Knob_RangeDValue) * 100 / _KNOB_FULL_ADV)) / 100) + _Knob_RangeLowValue;
#else
    //非线性输出
    // _Knob_Value = (u16)((u16)((u16)adv * (u16)((u16)(_KNOB_HIGH_VOLUE-_KNOB_LOW_VOLUE) * 100 / _KNOB_FULL_ADV)) / 100) + _KNOB_LOW_VOLUE;
    //线性输出，旋钮旋到中间输出中间值
    _Knob_Value = (_KNOB_PULLUP_RESISTOR_VOLUE/_KNOB_FULL_RESISTOR_VOLUE)*(u16)(_KNOB_HIGH_VOLUE-_KNOB_LOW_VOLUE)*adv/(_KNOB_ADC_FULL_ADV-adv) + _KNOB_LOW_VOLUE;
#endif
    if(_Knob_Value > _KNOB_HIGH_VOLUE)_Knob_Value = _KNOB_HIGH_VOLUE;
    else if(_Knob_Value < _KNOB_LOW_VOLUE)_Knob_Value = _KNOB_LOW_VOLUE;
    return _Knob_Value;
}
#ifdef _KNOB_USE_SET_RANGE
void Knob_SetRange(u16 minValue,u16 maxValue)
{
    _Knob_RangeDValue=maxValue-minValue;
    _Knob_RangeLowValue=minValue;
}
#endif

//自动刷新，间隔10~100ms执行一次
void Knob_Task(void)
{
    if (Knob_mRun)
    {
        static u16 knob_ValuePre = 0;
        u8 adv;

        _KNOB_SetADCH_ANALOG();
        adv = _KNOB_GetADValue();
        _KNOB_SetADCH_DIGIT();
        // if(adv>_KNOB_FULL_ADV)
        // {
        //     adv=_KNOB_FULL_ADV;
        // }
        //Ex:_Knob_Value = adv * (5000 - 3000)/127 + 3000;
        // _Knob_Value = (u16)((u32)((u32)adv * (u16)((u32)(_KNOB_HIGH_VOLUE - _KNOB_LOW_VOLUE) * 100 / 127)) / 100) + _KNOB_LOW_VOLUE;
#ifdef _KNOB_USE_SET_RANGE
        _Knob_Value = (u16)((u32)((u32)adv * (u16)((u32)(_Knob_RangeDValue) * 100 / 127)) / 100) + _Knob_RangeLowValue;
#else
    _Knob_Value = (_KNOB_PULLUP_RESISTOR_VOLUE/_KNOB_FULL_RESISTOR_VOLUE)*(u16)(_KNOB_HIGH_VOLUE-_KNOB_LOW_VOLUE)*adv/(_KNOB_ADC_FULL_ADV-adv) + _KNOB_LOW_VOLUE;
#endif

        if (_Knob_Value != knob_ValuePre)
        {
            if (_Knob_Value > knob_ValuePre)
            {
                if ((_Knob_Value - knob_ValuePre) >= _KNOB_FULL_ADV_SCALE)
                {
                    knob_ValuePre = _Knob_Value;
                    Knob_mEvent = KNOB_EV_CHANGED;
                }
            }
            else
            {
                if ((knob_ValuePre - _Knob_Value) >= _KNOB_FULL_ADV_SCALE)
                {
                    knob_ValuePre = _Knob_Value;
                    Knob_mEvent = KNOB_EV_CHANGED;
                }
            }
        }
    }

    if (Knob_mEvent != KNOB_EV_NULL)
    {
        Knob_Event(Knob_mEvent);
        Knob_mEvent = KNOB_EV_NULL;
    }
}